package javaer.starter.idea.window.component;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import javaer.starter.idea.util.ThreadUtils;

/**
 * 进度条组件
 *
 * @author yangzhen
 * @date 2023/7/24 16:23
 * @since 1.0.0
 */
public class ProgressComponent {

    /**
     * 后台进程的标题
     */
    private String progressTitle;
    /**
     * 进度条标题
     */
    private String title;
    /**
     * 进度的最大值
     */
    private int total;
    /**
     * 当前进度
     */
    public volatile int current;
    /**
     * 自定义任务
     */
    private TaskRunner taskRunner;
    /**
     * 任务执行回调
     */
    private TaskAfter taskAfter;

    public ProgressComponent(String title, int total, TaskRunner taskRunner) {
        this(title, total, taskRunner, null);
    }

    public ProgressComponent(String title, int total, TaskRunner taskRunner, TaskAfter taskAfter) {
        this("Long Running Task", title, total, taskRunner, taskAfter);
    }

    public ProgressComponent(String progressTitle, String title, int total, TaskRunner taskRunner, TaskAfter taskAfter) {
        this.progressTitle = progressTitle;
        this.total = total;
        this.current = 0;
        this.taskRunner = taskRunner;
        this.title = title;
        this.taskAfter = taskAfter;
    }

    public void run() {
        // UI组件的进程不能直接同步执行进度条
        // 初始化进度指示器，默认最大值为1.0，表示完成百分之百
        ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> {
            ApplicationManager.getApplication().runReadAction(() -> {

                ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator();
                progressIndicator.setText(title);
                progressIndicator.setIndeterminate(false); // 设置为false表示不确定进度，即显示进度条

                ProgressManager.getInstance().run(new Task.Backgroundable(null, progressTitle, true) {
                    @Override
                    public void run(ProgressIndicator indicator) {
                        try {
                            ThreadUtils.sleepMs(500);
                            taskRunner.run();
                        } catch (Exception exception) {
                            throw new RuntimeException(exception.getMessage());
                        }
                    }
                });

                while (!progressIndicator.isCanceled() && current < total) {
                    ThreadUtils.sleepMs(100);
                    double percentage = (double) current / total;
                    progressIndicator.setText2(String.format("%.2f%%", percentage * 100));
                    progressIndicator.setFraction(percentage);
                }
                ThreadUtils.sleepMs(1000);
                progressIndicator.setText2(String.format("%.2f%%", 100.00));
                progressIndicator.setFraction(100.00);
                if (taskAfter != null) {
                    taskAfter.after();
                }
            });
        }, "处理中", true, null);
    }

    public interface TaskRunner {
        void run() throws Exception;
    }

    public interface TaskAfter {
        void after();
    }
}
